package com.android.VideoCamera_0;

import java.io.File;
import java.io.IOException;
import java.lang.System;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.Bundle;
import android.view.Display;
import android.view.Menu;
import android.view.SubMenu;
import android.view.SurfaceView;
import android.view.View;
import android.view.MenuItem;
import android.view.SurfaceHolder;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.util.Log;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore.Images.Thumbnails;
import android.provider.MediaStore.Video;

public class VideoCamera_0 extends Activity implements View.OnClickListener,
		SurfaceHolder.Callback, MenuItem.OnMenuItemClickListener {

	public class TimeLapse {
		public boolean enable = false;
		public double rate = 0.0;
	}

	private class MyHandler extends Handler {
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case MSG_UPDATE_RECORD_TIME: {
				updateRecordingTime();
				break;
			}
			}
		}
	}

	private static class AllProfiles {
		public static final int NORMAL_INDEX = 6; // which range is supported
													// profiles in normal
													// mode:0~6
		public static final String[] key = { "1080P", "720P", "480P", "CIF",
				"HIGH", "LOW", "QCIF", "Time Lapse 1080P", "Time Lapse 720P",
				"Time Lapse 480P", "Time Lapse CIF", "Time Lapse HIGH",
				"Time Lapse LOW", "Time Lapse QCIF" };
		public static final int[] value = { CamcorderProfile.QUALITY_1080P,
				CamcorderProfile.QUALITY_720P, CamcorderProfile.QUALITY_480P,
				CamcorderProfile.QUALITY_CIF, CamcorderProfile.QUALITY_HIGH,
				CamcorderProfile.QUALITY_LOW, CamcorderProfile.QUALITY_QCIF,
				CamcorderProfile.QUALITY_TIME_LAPSE_1080P,
				CamcorderProfile.QUALITY_TIME_LAPSE_720P,
				CamcorderProfile.QUALITY_TIME_LAPSE_480P,
				CamcorderProfile.QUALITY_TIME_LAPSE_CIF,
				CamcorderProfile.QUALITY_TIME_LAPSE_HIGH,
				CamcorderProfile.QUALITY_TIME_LAPSE_LOW,
				CamcorderProfile.QUALITY_TIME_LAPSE_QCIF };
	}

	private class SupportedProfiles {
		public SupportedProfiles() {
			// TODO Auto-generated constructor stub
			mNormalIndex = -1;
			mKeys = new ArrayList<String>();
			mValues = new ArrayList<Integer>();
		}

		public int mNormalIndex; // which range is supported profiles in normal
									// mode
		public int mSensorId;
		public ArrayList<String> mKeys;
		public ArrayList<Integer> mValues;
	}

	private static String TAG = "VideoCamera_0";
	private static final int MSG_UPDATE_RECORD_TIME = 0;

	private int mCameraId = 0;
	private int mNumberOfCameras = 0;

	private SurfaceView mVideoPreview = null;
	private SurfaceHolder mSurfaceHolder = null;
	private Button mButtonStartStop = null;
	private TextView mTextViewLapsing = null;
	private TextView mTextViewTiming = null;
	private ImageView mThumbnailView = null;
	private SubMenu mSubMenuSelectedProfile = null;

	private android.hardware.Camera mCameraDevice = null;
	private android.hardware.Camera.Parameters mParameters = null;
	private android.media.MediaRecorder mRecorder = null;

	private CamcorderProfile mProfile = null;
	private ContentValues mCurrentVideoValues;
	private Uri mCurrentVideoUri = null;
	private ContentResolver mContentResolver = null;

	private int mMaxVideoDurationInMs = 1000 * 60 * 1;
	private long mStartRecordingTimeMs = 0;
	private SupportedProfiles mSupportProfiles = null;

	private String mFilePath = "";
	private final String CAMERA_DIR = Environment.getExternalStorageDirectory()
			.toString() + "/DCIM/Camera";

	private boolean mRecording = false;
	private boolean mPreviewing = false;
	private boolean mNeedRefreshMenu = true; // and switch caemra~~~~~~~~~~~
	private boolean mTimelapseEnabledChanged = true;
	private TimeLapse mTimelapse = new TimeLapse();
	private MyHandler mHandler = null;

	private final int MENU_LAPSE_SELECT = 0;
	private final int MENU_GROUP_LAPSE = 0;
	private final int MENU_LAPSE_DISABLE = 0;
	private final int MENU_LAPSE_0125 = -125;
	private final int MENU_LAPSE_025 = -25;
	private final int MENU_LAPSE_05 = -5;
	private final int MENU_LAPSE_1 = 1;
	private final int MENU_LAPSE_2 = 2;
	private final int MENU_LAPSE_4 = 4;
	private final int MENU_LAPSE_8 = 8;
	private final int MENU_LAPSE_16 = 16;

	private static final int MENU_GROUP_PROFILE = 1;
	private static final int MENU_GROUP_SWITCH_CAMERA = 2;
	private static final int MENU_SWITCH_CAMERA = 0;

	private final int SEC_HAS_MS = 1000;
	private final int MIN_HAS_MS = 60 * SEC_HAS_MS;
	private final int HOUR_HAS_MS = 60 * MIN_HAS_MS;

	private double mExpectedTimeVal = 0;

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub
		super.onCreateOptionsMenu(menu);
		addBaseMenuItems(menu);
		return true;
	}

	private void addBaseMenuItems(Menu menu) {
		// TODO Auto-generated method stub
		SubMenu timeLapseSelect = menu.addSubMenu(Menu.NONE, MENU_LAPSE_SELECT,
				Menu.NONE, R.string.menu_lapse_l0);
		timeLapseSelect
				.add(MENU_GROUP_LAPSE, MENU_LAPSE_DISABLE, Menu.NONE,
						R.string.menu_lapse_l1_disable)
				.setOnMenuItemClickListener(this).setChecked(true);
		timeLapseSelect.add(MENU_GROUP_LAPSE, MENU_LAPSE_0125, Menu.NONE,
				R.string.menu_lapse_l1_0125).setOnMenuItemClickListener(this);
		timeLapseSelect.add(MENU_GROUP_LAPSE, MENU_LAPSE_025, Menu.NONE,
				R.string.menu_lapse_l1_025).setOnMenuItemClickListener(this);
		timeLapseSelect.add(MENU_GROUP_LAPSE, MENU_LAPSE_05, Menu.NONE,
				R.string.menu_lapse_l1_05).setOnMenuItemClickListener(this);
		timeLapseSelect.add(MENU_GROUP_LAPSE, MENU_LAPSE_1, Menu.NONE,
				R.string.menu_lapse_l1_1).setOnMenuItemClickListener(this);
		timeLapseSelect.add(MENU_GROUP_LAPSE, MENU_LAPSE_2, Menu.NONE,
				R.string.menu_lapse_l1_2).setOnMenuItemClickListener(this);
		timeLapseSelect.add(MENU_GROUP_LAPSE, MENU_LAPSE_4, Menu.NONE,
				R.string.menu_lapse_l1_4).setOnMenuItemClickListener(this);
		timeLapseSelect.add(MENU_GROUP_LAPSE, MENU_LAPSE_8, Menu.NONE,
				R.string.menu_lapse_l1_8).setOnMenuItemClickListener(this);
		timeLapseSelect.add(MENU_GROUP_LAPSE, MENU_LAPSE_16, Menu.NONE,
				R.string.menu_lapse_l1_16).setOnMenuItemClickListener(this);
		timeLapseSelect.setGroupCheckable(MENU_GROUP_LAPSE, true, true);

		mSubMenuSelectedProfile = menu.addSubMenu(Menu.NONE, Menu.NONE,
				Menu.NONE, R.string.menu_profile_l0);

		if (mNumberOfCameras > 1) {
			if (mCameraId == 0) {
				menu.add(MENU_GROUP_SWITCH_CAMERA, MENU_SWITCH_CAMERA,
						Menu.NONE, R.string.switch_camera2front)
						.setOnMenuItemClickListener(this);
			} else {
				menu.add(MENU_GROUP_SWITCH_CAMERA, MENU_SWITCH_CAMERA,
						Menu.NONE, R.string.switch_camera2rear)
						.setOnMenuItemClickListener(this);
			}
		}
	}

	public boolean onMenuItemClick(MenuItem item) {
		// TODO Auto-generated method stub
		int selectedGroupId = item.getGroupId();
		double selected = item.getItemId();
		boolean enable_old = mTimelapse.enable;

		switch (selectedGroupId) {
		case MENU_GROUP_LAPSE: {
			if (selected == 0) {
				mTimelapse.enable = false;
				mTextViewLapsing.setVisibility(View.INVISIBLE);
			} else {
				mTimelapse.enable = true;
				mTimelapse.rate = 1.0 / getExpectedTimeVal(selected);
				mTextViewLapsing.setText(R.string.timeLapsing);
				mTextViewLapsing.setText((String) mTextViewLapsing.getText()
						+ mExpectedTimeVal + "s");
				mTextViewLapsing.setVisibility(View.VISIBLE);

			}

			item.setChecked(true);

			break;
		}

		case MENU_GROUP_PROFILE: {
			mProfile = CamcorderProfile.get(mCameraId, item.getItemId());
			item.setChecked(true);
			break;
		}

		case MENU_GROUP_SWITCH_CAMERA: {
			if(mRecording) {
				break;
			}
			if (selected == MENU_SWITCH_CAMERA) {
				switchCamera(mCameraId == 1 ? 0 : 1);
				
				if (mCameraId == 0) {
					item.setTitle(R.string.switch_camera2front);
				} else {
					item.setTitle(R.string.switch_camera2rear);
				}
			}
			break;
		}
		}

		if (enable_old != mTimelapse.enable) {
			mNeedRefreshMenu = true;
			mTimelapseEnabledChanged = true;
		} else {
			mTimelapseEnabledChanged = false;
		}
		return true;
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub
		if (mSubMenuSelectedProfile.size() != 0 && !mNeedRefreshMenu) {
			// already add menu items and camera id did't switch, return~
			return true;
		}
		Log.d(TAG, "@@ enter onPrepareOptionsMenu: supported "
				+ mSupportProfiles.mKeys.size() + "entries");
		super.onPrepareOptionsMenu(menu);
		mSubMenuSelectedProfile.clear();

		int start, end;
		if (!mTimelapse.enable) {
			start = 0;
			end = mSupportProfiles.mNormalIndex;
		} else {
			start = mSupportProfiles.mNormalIndex + 1;
			end = mSupportProfiles.mValues.size() - 1;
		}
		for (int i = start; i <= end; i++) {
			mSubMenuSelectedProfile.add(MENU_GROUP_PROFILE,
					mSupportProfiles.mValues.get(i), Menu.NONE,
					mSupportProfiles.mKeys.get(i)).setOnMenuItemClickListener(
					this);
		}
		mSubMenuSelectedProfile.getItem(1).setChecked(true); // not the highest
																// resolution(select
																// the second
																// one) , by
																// default
		mSubMenuSelectedProfile.setGroupCheckable(MENU_GROUP_PROFILE, true,
				true);

		mNeedRefreshMenu = false;
		return true;
	}

	public double getExpectedTimeVal(double val) {
		if (val < 0) {
			if (val >= -10) {
				mExpectedTimeVal = (-val) / 10;
			} else if (val >= -100) {
				mExpectedTimeVal = (-val) / 100;
			} else if (val >= -1000) {
				// no possible in theory
				mExpectedTimeVal = (-val) / 1000;
			}

		} else if (((int) val) == 0) {
			mExpectedTimeVal = 0;
		} else {
			mExpectedTimeVal = val;
		}

		return mExpectedTimeVal;
	}

	private void updateRecordingTime() {

		if (!mRecording) {
			mTextViewTiming.setVisibility(View.INVISIBLE);
			return;
		}

		long deltra = System.currentTimeMillis() - mStartRecordingTimeMs;
		long nextDelay = SEC_HAS_MS - deltra % SEC_HAS_MS;

		long hours = deltra / HOUR_HAS_MS;
		long minutes = deltra % HOUR_HAS_MS / MIN_HAS_MS;
		long seconds = deltra % HOUR_HAS_MS % MIN_HAS_MS / SEC_HAS_MS;

		mHandler.sendEmptyMessageDelayed(MSG_UPDATE_RECORD_TIME, nextDelay);
		String timeShow = "Rec ";
		if (Long.toString(hours).length() < 2) {
			timeShow += "0";
		}
		timeShow = timeShow + hours + ":";

		if (Long.toString(minutes).length() < 2) {
			timeShow += "0";
		}
		timeShow = timeShow + minutes + ":";

		if (Long.toString(seconds).length() < 2) {
			timeShow += "0";
		}
		timeShow += seconds;

		mTextViewTiming.setText(timeShow);
		mTextViewTiming.setVisibility(View.VISIBLE);
	}

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		Log.d(TAG, "@@@@_ onCreate()");
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		mVideoPreview = (SurfaceView) findViewById(R.id.video_preview);
		mButtonStartStop = (Button) findViewById(R.id.button_start_stop);
		mTextViewLapsing = (TextView) findViewById(R.id.textViewLapsing);
		mTextViewTiming = (TextView) findViewById(R.id.textViewTiming);
		mThumbnailView = (ImageView) findViewById(R.id.thumbnail_view);

		mNumberOfCameras = android.hardware.Camera.getNumberOfCameras();
		Log.d(TAG, "we get " + mNumberOfCameras + " cameras");
		mVideoPreview.setOnClickListener(this);
		mButtonStartStop.setOnClickListener(this);
		mThumbnailView.setOnClickListener(this);
		SurfaceHolder holder = mVideoPreview.getHolder();
		holder.addCallback(this);
		holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

		//
		// Thread previewThread = new Thread(new Runnable() {
		// public void run() {
		// startPreview();
		// }
		// });
		// previewThread.start();

		changeButtonText();
		mContentResolver = getContentResolver();
		mHandler = new MyHandler();
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		Log.d(TAG, "@@ onresume9()");

		mVideoPreview.setVisibility(View.VISIBLE);
		startPreview();
	}

	protected void onPause() {
		super.onPause();

		Log.d(TAG, "@@ onPause() called");
		mVideoPreview.setVisibility(View.INVISIBLE);
		stopRecord();
		stopPreview();

		mCameraDevice.lock();
		mCameraDevice.release();
		mCameraDevice = null;
	}

	public void switchCamera(int id) {
		if (mCameraId == id) {
			return;
		}

		Log.d(TAG, "@@@@ switch camera from " + mCameraId + " to " + id);
		stopPreview();
		mCameraDevice.release();
		mCameraDevice = null;
		mCameraId = id;
		startPreview();
		mNeedRefreshMenu = true;
		mTimelapseEnabledChanged = true;
	}

	public void startPreview() {

		if (mPreviewing) {
			stopPreview();
		}
		Log.d(TAG, "@@startPreview~~");
		initCamera();

		mCameraDevice.startPreview();
		Log.d(TAG, "starting preview");
		mPreviewing = true;

	}

	public void initCamera() {
		if (mCameraDevice == null) {
			mCameraDevice = android.hardware.Camera.open(mCameraId);
		}
		mParameters = mCameraDevice.getParameters();
		List<Size> mSupportedPreviewSizes = mParameters
				.getSupportedPreviewSizes();

		Size thisSize;
		String sizeString = new String();

		if (mSupportedPreviewSizes != null) {
			for (int i = 0; i < mSupportedPreviewSizes.size(); i++) {
				thisSize = mSupportedPreviewSizes.get(i);
				sizeString = sizeString + thisSize.width + "x"
						+ thisSize.height + ", ";
			}
			Log.d(TAG, "@@supported preview size:" + sizeString);
		}

		mSupportProfiles = new SupportedProfiles();
		mSupportProfiles.mSensorId = mCameraId;
		for (int i = 0; i < AllProfiles.value.length; i++) {
			if (CamcorderProfile.hasProfile(mSupportProfiles.mSensorId,
					AllProfiles.value[i])) {
				if (i <= AllProfiles.NORMAL_INDEX) {
					mSupportProfiles.mNormalIndex++;
				}
				mSupportProfiles.mKeys.add(AllProfiles.key[i]);
				mSupportProfiles.mValues.add(AllProfiles.value[i]);
				Log.d(TAG, "camera id_" + mSupportProfiles.mSensorId
						+ " profile " + AllProfiles.key[i] + " supported");
			}
		}

		thisSize = getOptimalPreviewSize(mSupportedPreviewSizes,
				(double) 720 / 480);
		mParameters.setPreviewSize(thisSize.width, thisSize.height);

		mCameraDevice.setParameters(mParameters);
		try {
			mCameraDevice.setPreviewDisplay(mSurfaceHolder);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	private Size getOptimalPreviewSize(List<Size> sizes, double targetRatio) {
		final double ASPECT_TOLERANCE = 0.05;
		if (sizes == null)
			return null;

		Size optimalSize = null;
		double minDiff = Double.MAX_VALUE;

		Display display = getWindowManager().getDefaultDisplay();
		int targetHeight = Math.min(display.getHeight(), display.getWidth());

		if (targetHeight <= 0) {
			// We don't know the size of SurefaceView, use screen height
			WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
			targetHeight = windowManager.getDefaultDisplay().getHeight();
		}

		// Try to find an size match aspect ratio and size
		for (Size size : sizes) {
			double ratio = (double) size.width / size.height;
			if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
				continue;
			if (Math.abs(size.height - targetHeight) < minDiff) {
				optimalSize = size;
				minDiff = Math.abs(size.height - targetHeight);
			}
		}

		if (optimalSize == null) {
			Log.v(TAG, "No preview size match the aspect ratio");
			minDiff = Double.MAX_VALUE;
			for (Size size : sizes) {
				if (Math.abs(size.height - targetHeight) < minDiff) {
					optimalSize = size;
					minDiff = Math.abs(size.height - targetHeight);
				}
			}
		}
		return optimalSize;
	}

	public void initRecorder() {

		mRecorder.setCamera(mCameraDevice);
		mRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
		mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
		// mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
		// mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);

		mRecorder.setMaxDuration(mMaxVideoDurationInMs);

		// so the mProfile may not exists, or need to refresh, so we need spec
		// one manually(as we checked the second item in onPreparemenuItem, we
		// select the second entry here
		if (mProfile == null || mTimelapseEnabledChanged) {
			Log.d(TAG, "!!!! manually set profile, mProfile:" + mProfile
					+ " mTimeLapseEnabledChanged:" + mTimelapseEnabledChanged);
			mProfile = CamcorderProfile
					.get(mCameraId,
							mSupportProfiles.mValues
									.get((mTimelapse.enable ? (mSupportProfiles.mNormalIndex + 2)
											: (1))));
			mTimelapseEnabledChanged = false;
		}

		Log.d(TAG,
				"using profile:++++++++++++++++++++++++++++++++++++++++++++++++++");
		Log.d(TAG, "fileFormat:" + mProfile.fileFormat + "\nvideoFrameRate:"
				+ mProfile.videoFrameRate + "\nSize:"
				+ mProfile.videoFrameWidth + "x" + mProfile.videoFrameHeight
				+ "\nvideoBitRate:" + mProfile.videoBitRate + "\naudioBitRate:"
				+ mProfile.audioBitRate + "\naudioChannels:"
				+ mProfile.audioChannels + "\naudioSampleRate:"
				+ mProfile.audioSampleRate + "\nvideoCodec:"
				+ mProfile.videoCodec + "\naudioCodec:" + mProfile.audioCodec);
		Log.d(TAG,
				"using profile:-----------------------------------------------");

		mRecorder.setProfile(mProfile);
		setCaptureRate(mTimelapse.rate);

		if (mTimelapse.enable) {
			/*
			 * Found that the audioencoder will not be set if use timelapse's
			 * profile, we need to set it manually otherwise it can't be set ,
			 * or we will get an error "audioencoder already been set".~~囧... so
			 * we need an 'if' here
			 */
			mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
		}

		mRecorder.setOutputFile(newPath());
		mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());

		try {
			mRecorder.prepare();
		} catch (IllegalStateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void setCaptureRate(double r) {

		if (mTimelapse.enable) {
			mRecorder.setCaptureRate(r);
		}
		Log.d(TAG,
				"@@ Time lapse enabled:"
						+ mTimelapse.enable
						+ (mTimelapse.enable ? (" set rate to:" + r)
								: ""));
	}

	public void stopPreview() {
		if (mPreviewing) {
			mCameraDevice.stopPreview();
			mPreviewing = false;
			Log.d(TAG, "stop Preview");
		}
	}

	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		// TODO Auto-generated method stub
		Log.d(TAG, "@@@@ surface changed");
		mSurfaceHolder = holder;
		try {
			if (holder.isCreating()) {
				mCameraDevice.setPreviewDisplay(mSurfaceHolder);
			} else {
				if (!(mPreviewing)) {
					stopRecord();
					startPreview();
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public void surfaceCreated(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		Log.d(TAG, "@@ surface created");

	}

	public void surfaceDestroyed(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		Log.d(TAG, "@@ surface destroyed");
		mSurfaceHolder = null;
	}

	public void onClick(View v) {
		// TODO Auto-generated method stub

		switch (v.getId()) {
		case R.id.button_start_stop: {
			if (mRecording) {
				stopRecord();
			} else {
				startRecord();
			}
			break;
		}

		case R.id.thumbnail_view: {
			viewLastVideo();
		}
		}

		changeButtonText();
	}

	public void changeButtonText() {
		if (mRecording) {
			mButtonStartStop.setText(R.string.stop);
		} else {
			mButtonStartStop.setText(R.string.start);
		}

	}

	public void viewLastVideo() {
		if (mRecording) {
			Log.d(TAG, "aquired to view last video while recording, ignore it");
			return;
		}

		if (mCurrentVideoUri == null) {
			Log.d(TAG,
					"aqurired to view last video while haven't record one, ignore it");
			return;
		}
		Intent intent = new Intent(Intent.ACTION_VIEW, mCurrentVideoUri);
		try {
			startActivity(intent);
		} catch (android.content.ActivityNotFoundException ex) {
			Log.e(TAG, "Couldn't view video " + mCurrentVideoUri, ex);
		}
	}

	public void startRecord() {

		if (mRecording) {
			return;
		}
		mRecorder = new MediaRecorder();

		mCameraDevice.unlock();
		initRecorder();

		Log.d(TAG, "@@@@ start recording");

		Toast.makeText(this, "starting record", Toast.LENGTH_SHORT).show();
		mStartRecordingTimeMs = System.currentTimeMillis();
		mRecorder.start();
		mRecording = true;
		updateRecordingTime();

	}

	public void stopRecord() {
		Log.d(TAG, "@@@@ stop recording");

		if (!mRecording) {
			return;
		}

		Toast.makeText(this, "video clip stored into:" + mFilePath,
				Toast.LENGTH_LONG).show();
		mRecorder.stop();

		mRecording = false;
		mCameraDevice.lock();

		registerVideo();
		updateThumbnailView();

		mRecorder.release();
	}

	public void updateThumbnailView() {
		Bitmap thumbnail = ThumbnailUtils.createVideoThumbnail(mFilePath,
				Thumbnails.MICRO_KIND);
		mThumbnailView.setImageBitmap(thumbnail);
	}

	public String newPath() {

		long dateTaken = System.currentTimeMillis();
		String title = createName(dateTaken);
		String filename = title + ".3gp";
		String cameraDirPath = CAMERA_DIR;
		String filePath = cameraDirPath + "/" + filename;
		File cameraDir = new File(cameraDirPath);
		cameraDir.mkdirs();
		ContentValues values = new ContentValues(7);
		values.put(Video.Media.TITLE, title);
		values.put(Video.Media.DISPLAY_NAME, filename);
		values.put(Video.Media.DATE_TAKEN, dateTaken);
		values.put(Video.Media.MIME_TYPE, "video/3gpp");
		values.put(Video.Media.DATA, filePath);
		mFilePath = filePath;

		mCurrentVideoValues = values;

		Log.d(TAG, "new file: " + mFilePath);
		return mFilePath;
	}

	private String createName(long dateTaken) {
		Date date = new Date(dateTaken);
		SimpleDateFormat dateFormat = new SimpleDateFormat(
				getString(R.string.video_file_name_format));
		return ("iTestVideo_"
				+ (mTimelapse.enable ? ("TimeLapse" + mTimelapse.rate) : "")
				+ "_" + dateFormat.format(date) + "_"
				+ mProfile.videoFrameWidth + "x" + mProfile.videoFrameHeight);
	}

	private void registerVideo() {

		Uri videoTable = Uri.parse("content://media/external/video/media");
		mCurrentVideoValues.put(Video.Media.SIZE, new File(mFilePath).length());
		try {
			mCurrentVideoUri = mContentResolver.insert(videoTable,
					mCurrentVideoValues);
		} catch (Exception e) {
			// We failed to insert into the database. This can happen if
			// the SD card is unmounted.
			mCurrentVideoUri = null;
			mFilePath = null;
		} finally {
			Log.v(TAG, "Current video URI: " + mCurrentVideoUri);
		}

		mCurrentVideoValues = null;
	}

}